#include "sdl_gametimer.h"
#include <string>
#include <list>

sdl_timer::sdl_timer(const std::string & n) : sdl_layer(0, n)
{
    if (!SDL_WasInit(SDL_INIT_VIDEO))
        _err("timer", "SDL hasn't been initialized");

    _msg("timer", 10, "tworzenie timera " << name());

    delta_ms = 10;

    old_ticks = -10;

    a_fps_count = 20;

    factor = 1.0;

    // ustawiamy jakiś czas żeby nie dzielić przez 0
    a_delta = 0.1;

    limit_fps = 0.0f;
}

void sdl_timer::update()
{
    wait();
    new_ticks = SDL_GetTicks();
    delta_ms = new_ticks - old_ticks;
    old_ticks = new_ticks;

    update_a_delta();
}

sdl_timer::~sdl_timer()
{
    _msg("timer", 5, "kasowanie timera " << name());
    a_delta_b.clear();
}

///ustaw ilość klatek do średniowania

void sdl_timer::set_a_count(int c)
{
    a_fps_count = c;
    a_delta_b.clear();
}

///ustaw limit klatek na sekundę (0=brak limitu)

void sdl_timer::set_limit(float l)
{
    limit_fps = l;
}

///ustaw mnożnik (przyspieszenie bądź spowolnienie)

void sdl_timer::set_factor(float f)
{
    factor = f;
}

///uaktualnianie średniego czasu pomiędzy taktami

void sdl_timer::update_a_delta()
{
    a_delta_b.push_back(dt());
    a_delta = 0.0f;
    float b_size = float(a_delta_b.size());

    if (b_size == a_fps_count)
        a_delta_b.pop_front();

    for (std::list<float>::iterator i = a_delta_b.begin(); i != a_delta_b.end(); i++)
        a_delta += *i;

    a_delta /= b_size;

    if (a_delta == 0)
        a_delta = dt();

}

///czekanie aż czas trwania ramki osiągnie limit

void sdl_timer::wait()
{
    if (limit_fps == 0.0f)
        return;

    long limit = long(1000.0f / limit_fps);
    long t = SDL_GetTicks() - delta_ms;
    while ((long(SDL_GetTicks()) - t) <= limit) {
        SDL_Delay(1);
    }
}

template<> sdl_ptr<sdl_timer> sdl_singleton<sdl_timer>::__field = NULL;
